/* eslint-disable no-case-declarations */
/* eslint-disable import/prefer-default-export */
/* eslint-disable class-methods-use-this */
/* eslint-disable no-unused-vars */
/* eslint-disable max-classes-per-file */
import Konva from 'konva'
import { IKonvaPen } from '@/components/konvaUnits/tools/IKonvaPen'
import KonvaUtils from '@/components/konvaUnits/utils/konvaUtils'
import { drawDoorGroup } from '@/components/konvaUnits/common/door'
import { useStore } from '@/store/index'

export class DoorPen implements IKonvaPen {
  status: 'waiting' | 'drawing' | 'disable' = 'waiting'

  points!: number[]

  beginPos!: number[]

  endPos!: number[]

  angle: number = 0

  text: number[] = [0]

  beginPillar!: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 }

  endPillar!: {
    id: ''
    x: 0
    y: 0
    rotation: 0
    width: 0
    height: 0
  }

  konvaGroup!: Konva.Group

  mousedown(layer: Konva.Layer, points: number[], node: object): void {
    if (points === undefined || this.status === 'disable') return
    const store = useStore()

    switch (this.status) {
      case 'waiting':
        this.status = 'drawing'
        this.beginPos = points
        if (node instanceof Konva.Rect && node.attrs.id.search('pillar') !== -1) {
          this.beginPillar = node.attrs
        } else {
          this.beginPillar = {
            id: '',
            x: this.beginPos[0],
            y: this.beginPos[1],
            rotation: 0,
            width: 0,
            height: 0
          }
        }
        this.konvaGroup = new Konva.Group({ id: 'pen' })
        layer.add(this.konvaGroup)
        break
      case 'drawing':
        this.status = 'waiting'
        this.endPos = points
        if (
          node instanceof Konva.Rect &&
          node.attrs.id.search('pillar') !== -1 &&
          node.attrs.id.search('pen') === -1
        ) {
          this.endPillar = node.attrs
          this.endPos = [node.attrs.x, node.attrs.y]
        } else {
          this.endPillar = {
            id: '',
            x: this.beginPos[0],
            y: this.beginPos[1],
            rotation: 0,
            width: 0,
            height: 0
          }
          this.endPos = points
        }
        this.points = [this.beginPos[0], this.beginPos[1], this.endPos[0], this.endPos[1]]
        this.konvaGroup.remove()
        const id = `doorGroup${store.drawing.history.size + 1}`
        const doorGroup = this.createDoor(id, store.globalParam.plottingScale)
        if (doorGroup !== null) {
          layer.add(doorGroup)
          const children = doorGroup.getChildren().map((child) => {
            return child.id()
          })
          store.drawingAction.setHistory(id, children)
        }
        break
      default:
        break
    }
  }

  mousemove(points: number[], node: object): void {
    const store = useStore()
    if (points === undefined || this.status !== 'drawing') return
    this.konvaGroup.removeChildren()
    if (
      node instanceof Konva.Rect &&
      node.attrs.id.search('pillar') !== -1 &&
      node.attrs.id.search('pen') === -1
    ) {
      this.endPillar = node.attrs
      this.endPos = [node.attrs.x, node.attrs.y]
    } else {
      this.endPos = points
      this.endPillar = {
        id: '',
        x: points[0],
        y: points[1],
        rotation: 0,
        width: 0,
        height: 0
      }
    }
    this.createLine(
      this.konvaGroup,
      'pen',
      store.globalParam.plottingScale,
      false,
      store.globalParam.penType === 'sample'
    )
  }

  mouseup(points: number[], node: object): void {}

  click(e: any): void {
    throw new Error('Method not implemented.')
  }

  clean() {
    if (this.konvaGroup) this.konvaGroup.remove()
    this.points = [0, 0, 0, 0]
    this.beginPos = [0, 0]
    this.endPos = [0, 0]
    this.status = 'waiting'
  }

  createDoor(id: string, scale: number) {
    const lineLength = Math.round(KonvaUtils.getPositionLength(this.beginPos, this.endPos))
    const fixLine = KonvaUtils.fixRadian(
      this.beginPos,
      KonvaUtils.getAngle(this.beginPos, this.endPos),
      lineLength
    )
    this.text = [KonvaUtils.getRealLength(lineLength, scale)]
    this.points = fixLine.points
    this.angle = fixLine.lineAngle

    const { door, points } = drawDoorGroup(
      id,
      this.beginPos,
      this.text[0],
      this.angle,
      scale,
      this.beginPillar,
      this.endPillar,
      true
    )
    if (door !== null) return door
    return null
  }

  createLine(group: Konva.Group, id: string, scale: number, addStore: boolean, drawLine: boolean) {
    const lineLength = Math.round(KonvaUtils.getPositionLength(this.beginPos, this.endPos))
    const fixLine = KonvaUtils.fixRadian(
      this.beginPos,
      KonvaUtils.getAngle(this.beginPos, this.endPos),
      lineLength
    )
    this.text = [KonvaUtils.getRealLength(lineLength, scale)]
    this.points = fixLine.points
    this.angle = fixLine.lineAngle
    if (!drawLine) {
      const { door, points } = drawDoorGroup(
        id,
        this.beginPos,
        this.text[0],
        this.angle,
        scale,
        this.beginPillar,
        this.endPillar,
        addStore
      )
      if (door !== null) group.add(door)
    } else {
      const fence = new Konva.Line({
        points: this.points,
        stroke: 'grey'
      })
      const bottomText = new Konva.Text({
        x: this.points[0] + (this.points[2] - this.points[0]) / 2 + 10,
        y: this.points[1] + (this.points[3] - this.points[1]) / 2,
        text: this.text[0].toString(),
        padding: 2,
        fill: 'black'
      })
      group.add(fence, bottomText)
    }
  }
}
